From b721370354c875efe900e2a33ba1f6dd07946dc5 Mon Sep 17 00:00:00 2001 From: Kegan Maher Date: Tue, 15 Aug 2023 17:22:17 +0000 Subject: [PATCH] refactor(EligibilityVerifier): references form class verifier instance can create an instance of its form class --- benefits/core/migrations/0001_initial.py | 14 +---------- benefits/core/models.py | 30 ++++++++++-------------- tests/pytest/conftest.py | 9 ------- tests/pytest/core/test_models.py | 22 +++++++++++++++++ 4 files changed, 36 insertions(+), 39 deletions(-) diff --git a/benefits/core/migrations/0001_initial.py b/benefits/core/migrations/0001_initial.py index 6746ad65ce..cbdc8ba193 100644 --- a/benefits/core/migrations/0001_initial.py +++ b/benefits/core/migrations/0001_initial.py @@ -46,19 +46,7 @@ class Migration(migrations.Migration): ("jws_signing_alg", models.TextField(null=True)), ("selection_label_template", models.TextField()), ("start_template", models.TextField(null=True)), - ("form_title", models.TextField(null=True)), - ("form_headline", models.TextField(null=True)), - ("form_blurb", models.TextField(null=True)), - ("form_sub_label", models.TextField(null=True)), - ("form_sub_help_text", models.TextField(null=True)), - ("form_sub_placeholder", models.TextField(null=True)), - ("form_sub_pattern", models.TextField(null=True)), - ("form_input_mode", models.TextField(null=True)), - ("form_max_length", models.PositiveSmallIntegerField(null=True)), - ("form_name_label", models.TextField(null=True)), - ("form_name_help_text", models.TextField(null=True)), - ("form_name_placeholder", models.TextField(null=True)), - ("form_name_max_length", models.PositiveSmallIntegerField(null=True)), + ("form_class", models.TextField(null=True)), ( "auth_provider", models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to="core.authprovider"), diff --git a/benefits/core/models.py b/benefits/core/models.py index 31138ddb5b..11df8b2698 100644 --- a/benefits/core/models.py +++ b/benefits/core/models.py @@ -1,6 +1,7 @@ """ The core application: Common model definitions. """ +import importlib import logging from django.conf import settings @@ -111,23 +112,8 @@ class EligibilityVerifier(models.Model): auth_provider = models.ForeignKey(AuthProvider, on_delete=models.PROTECT, null=True) selection_label_template = models.TextField() start_template = models.TextField(null=True) - form_title = models.TextField(null=True) - form_headline = models.TextField(null=True) - form_blurb = models.TextField(null=True) - form_sub_label = models.TextField(null=True) - form_sub_help_text = models.TextField(null=True) - form_sub_placeholder = models.TextField(null=True) - # A regular expression used to validate the 'sub' API field before sending to this verifier - form_sub_pattern = models.TextField(null=True) - # Input mode can be "numeric", "tel", "search", etc. to override default "text" keyboard on mobile devices - form_input_mode = models.TextField(null=True) - # The maximum length accepted for the 'sub' API field before sending to this verifier - form_max_length = models.PositiveSmallIntegerField(null=True) - form_name_label = models.TextField(null=True) - form_name_help_text = models.TextField(null=True) - form_name_placeholder = models.TextField(null=True) - # The maximum length accepted for the 'name' API field before sending to this verifier - form_name_max_length = models.PositiveSmallIntegerField(null=True) + # reference to a form class used by this Verifier, e.g. benefits.app.forms.FormClass + form_class = models.TextField(null=True) def __str__(self): return self.name @@ -147,6 +133,16 @@ def uses_auth_verification(self): """True if this Verifier verifies via the auth provider. False otherwise.""" return self.is_auth_required and self.auth_provider.supports_claims_verification + def form_instance(self, *args, **kwargs): + """Return an instance of this verifier's form, or None.""" + if not bool(self.form_class): + return None + + module_name, class_name = self.form_class.rsplit(".", 1) + FormClass = getattr(importlib.import_module(module_name), class_name) + + return FormClass(*args, **kwargs) + @staticmethod def by_id(id): """Get an EligibilityVerifier instance by its ID.""" diff --git a/tests/pytest/conftest.py b/tests/pytest/conftest.py index f264c29765..18d228a246 100644 --- a/tests/pytest/conftest.py +++ b/tests/pytest/conftest.py @@ -111,15 +111,6 @@ def model_EligibilityVerifier(model_PemData, model_EligibilityType): eligibility_type=model_EligibilityType, public_key=model_PemData, selection_label_template="eligibility/includes/selection-label.html", - form_title="Form", - form_headline="Form", - form_blurb="Form Blurb", - form_sub_label="Sub", - form_sub_help_text="Sub Help Text", - form_sub_placeholder="Sub", - form_name_label="Name", - form_name_help_text="Name Help Text", - form_name_placeholder="Name", ) return verifier diff --git a/tests/pytest/core/test_models.py b/tests/pytest/core/test_models.py index a9ae9c9d28..1ba7f2854d 100644 --- a/tests/pytest/core/test_models.py +++ b/tests/pytest/core/test_models.py @@ -121,6 +121,28 @@ def test_EligibilityVerifier_str(model_EligibilityVerifier): assert str(model_EligibilityVerifier) == model_EligibilityVerifier.name +class TestFormClass: + """A class for testing EligibilityVerifier form references.""" + + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + + +@pytest.mark.django_db +def test_EligibilityVerifier_form_instance(model_EligibilityVerifier): + model_EligibilityVerifier.form_class = f"{__name__}.TestFormClass" + model_EligibilityVerifier.save() + + args = (1, "2") + kwargs = {"one": 1, "two": "2"} + form_instance = model_EligibilityVerifier.form_instance(*args, **kwargs) + + assert isinstance(form_instance, TestFormClass) + assert form_instance.args == args + assert form_instance.kwargs == kwargs + + @pytest.mark.django_db def test_EligibilityVerifier_by_id_matching(model_EligibilityVerifier): verifier = EligibilityVerifier.by_id(model_EligibilityVerifier.id)