Skip to content
Snippets Groups Projects
Commit 283994c6 authored by Todd Dembrey's avatar Todd Dembrey
Browse files

Defer the addition of forms to the workflow within the view

parent a621fe48
No related branches found
No related tags found
No related merge requests found
...@@ -49,6 +49,12 @@ class PhaseFactory(factory.Factory): ...@@ -49,6 +49,12 @@ class PhaseFactory(factory.Factory):
new_class = type(model_class.__name__, (model_class,), {'actions': actions}) new_class = type(model_class.__name__, (model_class,), {'actions': actions})
return new_class(*args, **kwargs) return new_class(*args, **kwargs)
@classmethod
def _build(cls, model_class, *args, **kwargs):
# defer to create because parent uses build
return cls._create(model_class, *args, **kwargs)
class StageFactory(factory.Factory): class StageFactory(factory.Factory):
class Meta: class Meta:
model = Stage model = Stage
...@@ -63,18 +69,38 @@ class StageFactory(factory.Factory): ...@@ -63,18 +69,38 @@ class StageFactory(factory.Factory):
@classmethod @classmethod
def _create(cls, model_class, *args, **kwargs): def _create(cls, model_class, *args, **kwargs):
# Returns a new class
phases = kwargs.pop('phases')
name = kwargs.pop('name')
return type(model_class.__name__, (model_class,), {'phases': phases, 'name': name})
@classmethod
def _build(cls, model_class, *args, **kwargs):
# returns an instance of the stage class
phases = kwargs.pop('phases') phases = kwargs.pop('phases')
new_class = type(model_class.__name__, (model_class,), {'phases': phases}) name = kwargs.pop('name')
new_class = type(model_class.__name__, (model_class,), {'phases': phases, 'name': name})
return new_class(*args, **kwargs) return new_class(*args, **kwargs)
class WorkflowFactory(factory.Factory): class WorkflowFactory(factory.Factory):
class Meta: class Meta:
model = Workflow model = Workflow
inline_args = ('name', 'stages',) rename = {'stages': 'stage_classes'}
class Params: class Params:
num_stages = factory.Faker('random_int', min=1, max=3) num_stages = factory.Faker('random_int', min=1, max=3)
name = factory.Faker('word') name = factory.Faker('word')
stages = ListSubFactory(StageFactory, count=factory.SelfAttribute('num_stages')) stages = ListSubFactory(StageFactory, count=factory.SelfAttribute('num_stages'))
@factory.LazyAttribute
def forms(self):
return [Form() for _ in range(self.num_stages)]
@classmethod
def _create(cls, model_class, *args, **kwargs):
name = kwargs.pop('name')
stages = kwargs.pop('stage_classes')
new_class = type(model_class.__name__, (model_class,), {'name': name, 'stage_classes': stages})
return new_class(*args, **kwargs)
...@@ -8,11 +8,13 @@ from .factories import ActionFactory, PhaseFactory, StageFactory, WorkflowFactor ...@@ -8,11 +8,13 @@ from .factories import ActionFactory, PhaseFactory, StageFactory, WorkflowFactor
class TestWorkflowCreation(SimpleTestCase): class TestWorkflowCreation(SimpleTestCase):
def test_can_create_workflow(self): def test_can_create_workflow(self):
name = 'single_stage'
stage = StageFactory() stage = StageFactory()
workflow = Workflow(name, [stage]) class NewWorkflow(Workflow):
self.assertEqual(workflow.name, name) name = 'single_stage'
self.assertCountEqual(workflow.stages, [stage]) stage_classes = [stage]
workflow = NewWorkflow([Form()])
self.assertEqual(workflow.name, NewWorkflow.name)
self.assertEqual(len(workflow.stages), 1)
def test_returns_first_phase_if_no_arg(self): def test_returns_first_phase_if_no_arg(self):
workflow = WorkflowFactory(num_stages=1, stages__num_phases=1) workflow = WorkflowFactory(num_stages=1, stages__num_phases=1)
...@@ -49,11 +51,11 @@ class TestStageCreation(SimpleTestCase): ...@@ -49,11 +51,11 @@ class TestStageCreation(SimpleTestCase):
self.assertEqual(stage.form, form) self.assertEqual(stage.form, form)
def test_can_get_next_phase(self): def test_can_get_next_phase(self):
stage = StageFactory(num_phases=2) stage = StageFactory.build(num_phases=2)
self.assertEqual(stage.next(stage.phases[0]), stage.phases[1]) self.assertEqual(stage.next(stage.phases[0]), stage.phases[1])
def test_get_none_if_no_next_phase(self): def test_get_none_if_no_next_phase(self):
stage = StageFactory(num_phases=1) stage = StageFactory.build(num_phases=1)
self.assertEqual(stage.next(stage.phases[0]), None) self.assertEqual(stage.next(stage.phases[0]), None)
......
from django.forms import Form
from django.shortcuts import render from django.shortcuts import render
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from .workflow import single_stage, two_stage from .workflow import SingleStage, DoubleStage
workflows = [single_stage, two_stage] workflows = [SingleStage, DoubleStage]
def demo_workflow(request, wf_id): def demo_workflow(request, wf_id):
workflow = workflows[int(wf_id)-1] wf = int(wf_id)
workflow_class = workflows[wf-1]
workflow = workflow_class([Form()] * wf)
current_phase = request.POST.get('current') current_phase = request.POST.get('current')
if request.POST: if request.POST:
phase = workflow.process(current_phase, request.POST['action']) phase = workflow.process(current_phase, request.POST['action'])
......
import copy import copy
from typing import Dict, Iterator, Iterable, List, Sequence, Tuple, Union from typing import List, Sequence, Type, Union
from django.forms import Form from django.forms import Form
from django.utils.text import slugify from django.utils.text import slugify
class Workflow: class Workflow:
def __init__(self, name: str, stages: Sequence['Stage']) -> None: name: str = ''
self.name = name stage_classes: Sequence[Type['Stage']] = list()
self.stages = stages
def __init__(self, forms: Sequence[Form]) -> None:
if len(self.stage_classes) != len(forms):
raise ValueError('Number of forms does not equal the number of stages')
self.stages = [stage(form) for stage, form in zip(self.stage_classes, forms)]
def current(self, current_phase: Union[str, 'Phase']) -> Union['Phase', None]: def current(self, current_phase: Union[str, 'Phase']) -> Union['Phase', None]:
if isinstance(current_phase, Phase): if isinstance(current_phase, Phase):
...@@ -230,6 +235,12 @@ class ProposalStage(Stage): ...@@ -230,6 +235,12 @@ class ProposalStage(Stage):
rejected, rejected,
] ]
single_stage = Workflow('Single Stage', [ConceptStage(Form())])
two_stage = Workflow('Two Stage', [ConceptStage(Form()), ProposalStage(Form())]) class SingleStage(Workflow):
name = 'Single Stage'
stage_classes = [ConceptStage]
class DoubleStage(Workflow):
name = 'Two Stage'
stage_classes = [ConceptStage, ProposalStage]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment