bottleneckcrm/backend/webforms/tests/test_models.py
Ashwin 41250838ad Add comprehensive tests for web forms functionality
- Implement tests for web forms screen to ensure proper rendering and behavior on different devices.
- Create unit tests for web form model to validate JSON serialization and deserialization.
- Add tests for web forms provider to verify API interactions and state management.
- Ensure that publishing rules and field validations are correctly enforced in the tests.
2026-08-17 13:33:14 +05:30

134 lines
4.7 KiB
Python

"""Model-level guarantees for the webforms app.
These are the rules the database itself has to hold, as opposed to the
serializer rules tested elsewhere. A constraint that only exists in a
serializer is one a management command or a data migration can walk straight
past.
"""
import datetime
import pytest
from django.db import IntegrityError, transaction
from common.models import CustomFieldDefinition
from common.utils import LEAD_SOURCE
from webforms.models import WebForm, WebFormDailyStat, WebFormField
@pytest.mark.django_db
class TestWebFormField:
def _form(self, org_a):
return WebForm.objects.create(name="Contact us", org=org_a)
def test_a_lead_field_row_needs_no_custom_field(self, org_a):
field = WebFormField.objects.create(
form=self._form(org_a),
org=org_a,
order=0,
source=WebFormField.SOURCE_LEAD,
lead_field="email",
label="Email",
)
assert field.custom_field is None
def test_a_row_cannot_carry_both_a_lead_field_and_a_custom_field(self, org_a):
definition = CustomFieldDefinition.objects.create(
org=org_a,
target_model="Lead",
key="budget",
label="Budget",
field_type="number",
)
with pytest.raises(IntegrityError), transaction.atomic():
WebFormField.objects.create(
form=self._form(org_a),
org=org_a,
order=0,
source=WebFormField.SOURCE_LEAD,
lead_field="email",
custom_field=definition,
label="Both",
)
def test_a_row_cannot_carry_neither(self, org_a):
with pytest.raises(IntegrityError), transaction.atomic():
WebFormField.objects.create(
form=self._form(org_a),
org=org_a,
order=0,
source=WebFormField.SOURCE_LEAD,
lead_field="",
custom_field=None,
label="Neither",
)
def test_the_same_lead_field_cannot_appear_twice_on_one_form(self, org_a):
form = self._form(org_a)
WebFormField.objects.create(
form=form,
org=org_a,
order=0,
source=WebFormField.SOURCE_LEAD,
lead_field="email",
label="Email",
)
with pytest.raises(IntegrityError), transaction.atomic():
WebFormField.objects.create(
form=form,
org=org_a,
order=1,
source=WebFormField.SOURCE_LEAD,
lead_field="email",
label="Email again",
)
def test_the_same_lead_field_may_appear_on_two_different_forms(self, org_a):
"""The uniqueness is per form, not per org. Two forms both collecting
an email address is the normal case, not a conflict."""
for name in ("Contact us", "Request a demo"):
WebFormField.objects.create(
form=WebForm.objects.create(name=name, org=org_a),
org=org_a,
order=0,
source=WebFormField.SOURCE_LEAD,
lead_field="email",
label="Email",
)
assert WebFormField.objects.filter(lead_field="email").count() == 2
@pytest.mark.django_db
class TestWebFormDailyStat:
def test_one_row_per_form_per_day(self, org_a):
form = WebForm.objects.create(name="Contact us", org=org_a)
WebFormDailyStat.objects.create(
form=form, org=org_a, date=datetime.date(2026, 8, 16)
)
with pytest.raises(IntegrityError), transaction.atomic():
WebFormDailyStat.objects.create(
form=form, org=org_a, date=datetime.date(2026, 8, 16)
)
def test_the_same_day_on_two_forms_is_fine(self, org_a):
for name in ("Contact us", "Request a demo"):
WebFormDailyStat.objects.create(
form=WebForm.objects.create(name=name, org=org_a),
org=org_a,
date=datetime.date(2026, 8, 16),
)
assert WebFormDailyStat.objects.count() == 2
@pytest.mark.django_db
def test_lead_source_default_is_a_valid_lead_source_choice(org_a):
"""`Lead.source` declares choices=LEAD_SOURCE. Writing anything else into
it, as the legacy view does with a website URL, makes the row invisible to
every source-based filter and report."""
form = WebForm.objects.create(name="Contact us", org=org_a)
assert form.lead_source in dict(LEAD_SOURCE)
@pytest.mark.django_db
def test_a_form_is_unpublished_until_someone_publishes_it(org_a):
assert WebForm.objects.create(name="Contact us", org=org_a).is_published is False