Newer
Older
from collections import defaultdict
import datetime
from wagtail.wagtailcore.blocks import StreamBlock
from opentech.apply.funds.models import (
ApplicationForm,
FundType,
FundForm,
LabForm,
LabType,
Round,
from opentech.apply.users.tests.factories import UserFactory
from opentech.apply.users.groups import STAFF_GROUP_NAME
from . import blocks
Todd Dembrey
committed
__all__ = [
'FundTypeFactory',
'FundFormFactory',
'ApplicationFormFactory',
Todd Dembrey
committed
'RoundFactory',
Todd Dembrey
committed
'LabFactory',
'LabFormFactory',
]
def build_form(data, prefix=''):
extras = defaultdict(dict)
for key, value in data.items():
if 'form_fields' in key:
_, field, attr = key.split('__')
extras[field][attr] = value
form_fields = {}
for i, field in enumerate(blocks.CustomFormFieldsFactory.factories.keys()):
form_fields[f'{prefix}form_fields__{i}__{field}__'] = ''
for attr, value in extras[field].items():
form_fields[f'{prefix}form_fields__{i}__{field}__{attr}'] = value
return form_fields
class FundTypeFactory(wagtail_factories.PageFactory):
class Params:
workflow_stages = 1
# Will need to update how the stages are identified as Fund Page changes
workflow_name = factory.LazyAttribute(lambda o: list(FundType.WORKFLOWS.keys())[o.workflow_stages - 1])
@factory.post_generation
def forms(self, create, extracted, **kwargs):
if create:
fields = build_form(kwargs, prefix='form')
for _ in range(len(self.workflow_class.stage_classes)):
# Generate a form based on all defined fields on the model
FundFormFactory(
fund=self,
**fields,
)
class AbstractRelatedFormFactory(factory.DjangoModelFactory):
class Meta:
model = AbstractRelatedForm
abstract = True
form = factory.SubFactory('opentech.apply.funds.tests.factories.ApplicationFormFactory')
class FundFormFactory(AbstractRelatedFormFactory):
model = FundForm
fund = factory.SubFactory(FundTypeFactory, parent=None)
class ApplicationFormFactory(factory.DjangoModelFactory):
class Meta:
model = ApplicationForm
name = factory.Faker('word')
form_fields = blocks.CustomFormFieldsFactory
class RoundFactory(wagtail_factories.PageFactory):
class Meta:
model = Round
title = factory.Sequence('Round {}'.format)
start_date = factory.LazyFunction(datetime.date.today)
end_date = factory.LazyFunction(lambda: datetime.date.today() + datetime.timedelta(days=7))
lead = factory.SubFactory(UserFactory, groups__name=STAFF_GROUP_NAME)
class RoundFormFactory(AbstractRelatedFormFactory):
class Meta:
model = RoundForm
round = factory.SubFactory(RoundFactory, parent=None)
class LabFactory(wagtail_factories.PageFactory):
class Meta:
model = LabType
class Params:
workflow_stages = 1
number_forms = 1
# Will need to update how the stages are identified as Fund Page changes
workflow_name = factory.LazyAttribute(lambda o: list(FundType.WORKFLOWS.keys())[o.workflow_stages - 1])
class LabFormFactory(AbstractRelatedFormFactory):
class Meta:
model = LabForm
lab = factory.SubFactory(LabFactory, parent=None)
class FormDataFactory(factory.Factory):
def _create(self, *args, form_fields='{}', **kwargs):
form_fields = ApplicationSubmission.form_fields.field.to_python(form_fields)
form_data = {}
for field in form_fields:
try:
answer = kwargs[field.block_type]
# Get the factory and delegate to the block to make an answer
factory = blocks.CustomFormFieldsFactory.factories[field.block_type]
answer = factory.make_answer()
form_data[field.id] = answer
return form_data
class ApplicationSubmissionFactory(factory.DjangoModelFactory):
class Meta:
model = ApplicationSubmission
form_fields = blocks.CustomFormFieldsFactory
form_data = factory.SubFactory(FormDataFactory, form_fields=factory.SelfAttribute('..form_fields'))
page = factory.SubFactory(FundTypeFactory)
round = factory.SubFactory(RoundFactory)
user = factory.SubFactory(UserFactory)
@classmethod
def _generate(cls, strat, params):
params.update(**build_form(params))
return super()._generate(strat, params)