From 8d8ea1a22e020cffa173185ea065a850da29b53a Mon Sep 17 00:00:00 2001 From: Gabriel Hurley Date: Thu, 12 Jul 2012 13:00:45 -0700 Subject: [PATCH] Allow arbitrarily setting the entry point in a workflow. Change-Id: I45fed66f368305ffc60ca4cd1c4d1296c5351b02 --- horizon/tests/workflows_tests.py | 8 ++++++++ horizon/workflows/base.py | 18 +++++++++++++++++- horizon/workflows/views.py | 4 +++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/horizon/tests/workflows_tests.py b/horizon/tests/workflows_tests.py index 7fee9a952..9eda153c6 100644 --- a/horizon/tests/workflows_tests.py +++ b/horizon/tests/workflows_tests.py @@ -251,3 +251,11 @@ class WorkflowsTests(test.TestCase): ['', '', '']) + + def test_entry_point(self): + req = self.factory.get("/foo") + flow = TestWorkflow(req) + self.assertEqual(flow.get_entry_point(), "test_action_one") + + flow = TestWorkflow(req, entry_point="test_action_two") + self.assertEqual(flow.get_entry_point(), "test_action_two") diff --git a/horizon/workflows/base.py b/horizon/workflows/base.py index 92c8a8e1a..b0bb960b1 100644 --- a/horizon/workflows/base.py +++ b/horizon/workflows/base.py @@ -497,6 +497,13 @@ class Workflow(html.HTMLElement): In general the default common template should be used. Default: ``"horizon/common/_workflow.html"``. + .. attribute:: entry_point + + The slug of the step which should initially be active when the + workflow is rendered. This can be passed in upon initialization of + the workflow, or set anytime after initialization but before calling + either ``get_entry_point`` or ``render``. + .. attribute:: redirect_param_name The name of a parameter used for tracking the URL to redirect to upon @@ -519,7 +526,8 @@ class Workflow(html.HTMLElement): def __repr__(self): return "<%s: %s>" % (self.__class__.__name__, self.slug) - def __init__(self, request=None, context_seed=None, *args, **kwargs): + def __init__(self, request=None, context_seed=None, entry_point=None, + *args, **kwargs): super(Workflow, self).__init__(*args, **kwargs) if self.slug is None: raise AttributeError("The workflow %s must have a slug." @@ -528,6 +536,7 @@ class Workflow(html.HTMLElement): self.request = request self.depends_on = set([]) self.contributions = set([]) + self.entry_point = entry_point # Put together our steps in order. Note that we pre-register # non-default steps so that we can identify them and subsequently @@ -616,6 +625,11 @@ class Workflow(html.HTMLElement): This method takes into account both already-available data and errors within the steps. """ + # If we have a valid specified entry point, use it. + if self.entry_point: + if self.get_step(self.entry_point): + return self.entry_point + # Otherwise fall back to calculating the appropriate entry point. for step in self.steps: if step.has_errors: return step.slug @@ -623,6 +637,8 @@ class Workflow(html.HTMLElement): step._verify_contributions(self.context) except exceptions.WorkflowError: return step.slug + # If nothing else, just return the first step. + return self.steps[0].slug def _trigger_handlers(self, key): responses = [] diff --git a/horizon/workflows/views.py b/horizon/workflows/views.py index a8b9c4e27..535824613 100644 --- a/horizon/workflows/views.py +++ b/horizon/workflows/views.py @@ -70,8 +70,10 @@ class WorkflowView(generic.TemplateView): def get_workflow(self): """ Returns the instanciated workflow class. """ extra_context = self.get_initial() + entry_point = self.request.GET.get("step", None) workflow = self.workflow_class(self.request, - context_seed=extra_context) + context_seed=extra_context, + entry_point=entry_point) return workflow def get_context_data(self, **kwargs):