mirror of
https://github.com/jazzband/django-eav2.git
synced 2026-03-16 22:40:26 +00:00
251 lines
7.3 KiB
Python
251 lines
7.3 KiB
Python
import pytest
|
|
from django.contrib.admin.sites import AdminSite
|
|
from django.core.handlers.base import BaseHandler
|
|
from django.forms import ModelForm
|
|
from django.test import TestCase
|
|
from django.test.client import RequestFactory
|
|
|
|
import eav
|
|
from eav.admin import BaseEntityAdmin
|
|
from eav.forms import BaseDynamicEntityForm
|
|
from eav.models import Attribute, EnumGroup, EnumValue
|
|
from test_project.models import ExampleModel, M2MModel, Patient
|
|
|
|
|
|
class MockRequest(RequestFactory):
|
|
def request(self, **request):
|
|
"Construct a generic request object."
|
|
request = RequestFactory.request(self, **request)
|
|
handler = BaseHandler()
|
|
handler.load_middleware()
|
|
|
|
return request
|
|
|
|
|
|
class MockSuperUser:
|
|
def __init__(self):
|
|
self.is_active = True
|
|
self.is_staff = True
|
|
|
|
def has_perm(self, perm):
|
|
return True
|
|
|
|
|
|
request = MockRequest().request()
|
|
request.user = MockSuperUser()
|
|
|
|
|
|
class PatientForm(ModelForm):
|
|
class Meta:
|
|
model = Patient
|
|
fields = ("name", "email", "example")
|
|
|
|
|
|
class PatientDynamicForm(BaseDynamicEntityForm):
|
|
class Meta:
|
|
model = Patient
|
|
fields = ("name", "email", "example")
|
|
|
|
|
|
class M2MModelForm(ModelForm):
|
|
class Meta:
|
|
model = M2MModel
|
|
fields = ("name", "models")
|
|
|
|
|
|
class Forms(TestCase):
|
|
def setUp(self):
|
|
eav.register(Patient)
|
|
Attribute.objects.create(name="weight", datatype=Attribute.TYPE_FLOAT)
|
|
Attribute.objects.create(name="color", datatype=Attribute.TYPE_TEXT)
|
|
|
|
self.female = EnumValue.objects.create(value="Female")
|
|
self.male = EnumValue.objects.create(value="Male")
|
|
gender_group = EnumGroup.objects.create(name="Gender")
|
|
gender_group.values.add(self.female, self.male)
|
|
|
|
Attribute.objects.create(
|
|
name="gender",
|
|
datatype=Attribute.TYPE_ENUM,
|
|
enum_group=gender_group,
|
|
)
|
|
|
|
self.instance = Patient.objects.create(name="Jim Morrison")
|
|
|
|
def test_valid_submit(self):
|
|
self.instance.eav.color = "Blue"
|
|
form = PatientForm(self.instance.__dict__, instance=self.instance)
|
|
jim = form.save()
|
|
|
|
self.assertEqual(jim.eav.color, "Blue")
|
|
|
|
def test_invalid_submit(self):
|
|
form = PatientForm({"color": "Blue"}, instance=self.instance)
|
|
with self.assertRaises(ValueError):
|
|
form.save()
|
|
|
|
def test_valid_enums(self):
|
|
self.instance.eav.gender = self.female
|
|
form = PatientForm(self.instance.__dict__, instance=self.instance)
|
|
rose = form.save()
|
|
|
|
self.assertEqual(rose.eav.gender, self.female)
|
|
|
|
def test_m2m(self):
|
|
m2mmodel = M2MModel.objects.create(name="name")
|
|
model = ExampleModel.objects.create(name="name")
|
|
form = M2MModelForm({"name": "Lorem", "models": [model.pk]}, instance=m2mmodel)
|
|
form.save()
|
|
self.assertEqual(len(m2mmodel.models.all()), 1)
|
|
|
|
|
|
@pytest.fixture
|
|
def patient() -> Patient:
|
|
"""Return an eav enabled Patient instance."""
|
|
eav.register(Patient)
|
|
return Patient.objects.create(name="Jim Morrison")
|
|
|
|
|
|
@pytest.fixture
|
|
def create_attributes() -> None:
|
|
"""Create some Attributes to use for testing."""
|
|
Attribute.objects.create(name="weight", datatype=Attribute.TYPE_FLOAT)
|
|
Attribute.objects.create(name="color", datatype=Attribute.TYPE_TEXT)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@pytest.mark.parametrize(
|
|
("csv_data", "separator"),
|
|
[
|
|
("", ";"),
|
|
("justone", ","),
|
|
("one;two;three", ";"),
|
|
("alpha,beta,gamma", ","),
|
|
(None, ","),
|
|
],
|
|
)
|
|
def test_csvdynamicform(patient, csv_data, separator) -> None:
|
|
"""Ensure that a TYPE_CSV field works correctly with forms."""
|
|
Attribute.objects.create(name="csv", datatype=Attribute.TYPE_CSV)
|
|
patient.eav.csv = csv_data
|
|
patient.save()
|
|
patient.refresh_from_db()
|
|
|
|
form = PatientDynamicForm(
|
|
patient.__dict__,
|
|
instance=patient,
|
|
)
|
|
form.fields["csv"].separator = separator
|
|
assert form.is_valid()
|
|
jim = form.save()
|
|
|
|
expected_result = str(csv_data).split(separator) if csv_data else []
|
|
assert jim.eav.csv == expected_result
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_csvdynamicform_empty(patient) -> None:
|
|
"""Test to ensure an instance with no eav values is correct."""
|
|
form = PatientDynamicForm(
|
|
patient.__dict__,
|
|
instance=patient,
|
|
)
|
|
assert form.is_valid()
|
|
assert form.save()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@pytest.mark.usefixtures("create_attributes")
|
|
@pytest.mark.parametrize("define_fieldsets", [True, False])
|
|
def test_entity_admin_form(patient, define_fieldsets):
|
|
"""Test the BaseEntityAdmin form setup and dynamic fieldsets handling."""
|
|
admin = BaseEntityAdmin(Patient, AdminSite())
|
|
admin.readonly_fields = ("email",)
|
|
admin.form = BaseDynamicEntityForm
|
|
expected_fieldsets = 2
|
|
|
|
if define_fieldsets:
|
|
# Use all fields in Patient model
|
|
admin.fieldsets = (
|
|
(None, {"fields": ["name", "example"]}),
|
|
("Contact Info", {"fields": ["email"]}),
|
|
)
|
|
expected_fieldsets = 3
|
|
|
|
view = admin.change_view(request, str(patient.pk))
|
|
|
|
adminform = view.context_data["adminform"]
|
|
|
|
# Count the total fields in fieldsets
|
|
total_fields = sum(
|
|
len(fields_info["fields"]) for _, fields_info in adminform.fieldsets
|
|
)
|
|
|
|
# 3 for 'name', 'email', 'example'
|
|
expected_fields_count = Attribute.objects.count() + 3
|
|
|
|
assert total_fields == expected_fields_count
|
|
|
|
# Ensure our fieldset count is correct
|
|
assert len(adminform.fieldsets) == expected_fieldsets
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_entity_admin_form_no_attributes(patient):
|
|
"""Test the BaseEntityAdmin form with no Attributes created."""
|
|
admin = BaseEntityAdmin(Patient, AdminSite())
|
|
admin.readonly_fields = ("email",)
|
|
admin.form = BaseDynamicEntityForm
|
|
|
|
# Only fields defined in Patient model
|
|
expected_fields = 3
|
|
|
|
view = admin.change_view(request, str(patient.pk))
|
|
|
|
adminform = view.context_data["adminform"]
|
|
|
|
# Count the total fields in fieldsets
|
|
total_fields = sum(
|
|
len(fields_info["fields"]) for _, fields_info in adminform.fieldsets
|
|
)
|
|
|
|
# 3 for 'name', 'email', 'example'
|
|
assert total_fields == expected_fields
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_dynamic_form_renders_enum_choices():
|
|
"""
|
|
Test that enum choices render correctly in BaseDynamicEntityForm.
|
|
|
|
This test verifies the fix for issue #648 where enum choices weren't
|
|
rendering correctly in Django 4.2.17 due to QuerySet unpacking issues.
|
|
"""
|
|
# Setup
|
|
eav.register(Patient)
|
|
|
|
# Create enum values and group
|
|
female = EnumValue.objects.create(value="Female")
|
|
male = EnumValue.objects.create(value="Male")
|
|
gender_group = EnumGroup.objects.create(name="Gender")
|
|
gender_group.values.add(female, male)
|
|
|
|
Attribute.objects.create(
|
|
name="gender",
|
|
datatype=Attribute.TYPE_ENUM,
|
|
enum_group=gender_group,
|
|
)
|
|
|
|
# Create a patient
|
|
patient = Patient.objects.create(name="Test Patient")
|
|
|
|
# Initialize the dynamic form
|
|
form = PatientDynamicForm(instance=patient)
|
|
|
|
# Test rendering - should not raise any exceptions
|
|
rendered_form = form.as_p()
|
|
|
|
# Verify the form rendered and contains the enum choices
|
|
assert 'name="gender"' in rendered_form
|
|
assert f'value="{female.pk}">{female.value}' in rendered_form
|
|
assert f'value="{male.pk}">{male.value}' in rendered_form
|