from wagtail.tests.utils import WagtailPageTests from django import forms from django.core.files.uploadedfile import SimpleUploadedFile from dynamic_forms.models import ( CustomEmailForm, EmailFormField ) from dynamic_forms.forms import DynamicForm class CustomEmailFormTestCase(WagtailPageTests): def setUp(self): self.form = CustomEmailForm.objects.create( slug="test", title="Test Form", path="test", depth=0, numchild=0, live=True, has_unpublished_changes=False, from_address="comfy-test@egalitare.pl", to_address="comfy-dest@egalitare.pl", subject="Test Form", allow_attachments=False, ) EmailFormField.objects.create( label="Name", field_type="singleline", required=True, form=self.form ) EmailFormField.objects.create( label="Message", field_type="multiline", required=True, form=self.form ) EmailFormField.objects.create( label="Email", field_type="email", required=True, form=self.form ) EmailFormField.objects.create( label="Number", field_type="number", required=True, form=self.form ) EmailFormField.objects.create( label="URL", field_type="url", required=True, form=self.form ) EmailFormField.objects.create( label="Checkbox", field_type="checkbox", required=True, form=self.form ) EmailFormField.objects.create( label="Checkboxes", field_type="checkboxes", required=True, choices="a,b,c", form=self.form ) EmailFormField.objects.create( label="Dropdown", field_type="dropdown", required=True, choices="a,b,c", form=self.form ) EmailFormField.objects.create( label="MultiSelect", field_type="multiselect", required=True, choices="a,b,c", form=self.form ) EmailFormField.objects.create( label="Radio", field_type="radio", required=True, choices="a,b,c", form=self.form ) EmailFormField.objects.create( label="Date", field_type="date", required=True, form=self.form ) EmailFormField.objects.create( label="DateTime", field_type="datetime", required=True, form=self.form ) EmailFormField.objects.create( label="Hidden", field_type="hidden", required=True, form=self.form ) def test_generate_html_form_from_model(self): html_form = self.form.get_form() self.assertIsInstance(html_form, DynamicForm) self.assertEqual(len(html_form.fields), 14) self.assertEqual(html_form.fields["name"].label, "Name") self.assertEqual(html_form.fields["name"].required, True) self.assertEqual(html_form.fields["name"].widget.attrs["class"], "form-control") self.assertIsInstance( html_form.fields["name"], forms.CharField ) self.assertIsInstance( html_form.fields["message"], forms.CharField ) self.assertIsInstance( html_form.fields["email"].widget, forms.EmailInput ) self.assertIsInstance( html_form.fields["number"].widget, forms.NumberInput ) def test_create_form_submission_success_without_files(self): form_data = { # generate data for this class self.form.get_form() "name": "Test", "message": "Test message", "email": "test@test.com", "number": 1, "url": "http://example.com", "checkbox": True, "checkboxes": ["a", "b"], "dropdown": "a", "multiselect": ["a", "b"], "radio": "a", "date": "2020-01-01", "datetime": "2020-01-01 00:00:00", "hidden": "hidden", } form = self.form.get_form(form_data) self.assertTrue(form.is_valid()) # change field not to be required field = EmailFormField.objects.get( label="Name", form=self.form ) field.required = False field.save() form = self.form.get_form(form_data) self.assertTrue(form.is_valid()) # it should also work without this field form_data.pop("name") form = self.form.get_form(form_data) self.assertTrue(form.is_valid()) def test_create_form_submission_success_with_files(self): self.form.allow_attachments = True self.form.save() form_data = { # generate data for this class self.form.get_form() "name": "Test", "message": "Test message", "email": "test@test.com", "number": 1, "url": "http://example.com", "checkbox": True, "checkboxes": ["a", "b"], "dropdown": "a", "multiselect": ["a", "b"], "radio": "a", "date": "2020-01-01", "datetime": "2020-01-01 00:00:00", "hidden": "hidden" } files = { "attachments": [SimpleUploadedFile("test.txt", b"test")], } form = self.form.get_form(form_data, files=files) self.assertTrue(form.is_valid()) def test_create_form_submission_failure_without_files_missing_data(self): form_data = { # generate data for this class self.form.get_form() "message": "Test message", "email": "test@test.com", "number": 1, "url": "http://example.com", "checkbox": True, "checkboxes": ["a", "b"], "dropdown": "a", "multiselect": ["a", "b"], "radio": "a", "date": "2020-01-01", "datetime": "2020-01-01 00:00:00", "hidden": "hidden", } form = self.form.get_form(form_data) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors["name"], ['This field is required.']) form_data.pop("url") form = self.form.get_form(form_data) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 2) self.assertEqual(form.errors["name"], ['This field is required.']) self.assertEqual(form.errors["url"], ['This field is required.']) # make Field not required field = EmailFormField.objects.get( label="Hidden", form=self.form ) field.required = False field.save() # it should also work without this field form_data.pop("hidden") form = self.form.get_form(form_data) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 2) self.assertEqual(form.errors["name"], ['This field is required.']) self.assertEqual(form.errors["url"], ['This field is required.']) def test_create_form_submission_failure_with_files_missing_data(self): self.form.allow_attachments = True self.form.save() form_data = { # generate data for this class self.form.get_form() "message": "Test message", "email": "test@test.com", "number": 1, "url": "http://example.com", "checkbox": True, "checkboxes": ["a", "b"], "dropdown": "a", "multiselect": ["a", "b"], "radio": "a", "date": "2020-01-01", "datetime": "2020-01-01 00:00:00", "hidden": "hidden", } files = { "attachments": [SimpleUploadedFile("test.txt", b"test")], } form = self.form.get_form(form_data, files=files) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors["name"], ['This field is required.']) form_data.pop("url") form = self.form.get_form(form_data, files=files) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 2) self.assertEqual(form.errors["name"], ['This field is required.']) self.assertEqual(form.errors["url"], ['This field is required.']) # make Field not required field = EmailFormField.objects.get( label="Hidden", form=self.form ) field.required = False field.save() # it should also work without this field form_data.pop("hidden") form = self.form.get_form(form_data, files=files) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 2) self.assertEqual(form.errors["name"], ['This field is required.']) self.assertEqual(form.errors["url"], ['This field is required.']) # Now try without files form = self.form.get_form(form_data, files={}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 3) self.assertEqual(form.errors["name"], ['This field is required.']) self.assertEqual(form.errors["url"], ['This field is required.']) self.assertEqual(form.errors["attachments"], ['This field is required.']) def test_no_hidden_field_in_clean_data_success(self): form_data = { # generate data for this class self.form.get_form() "name": "Test", "message": "Test message", "email": "test@test.com", "number": 1, "url": "http://example.com", "checkbox": True, "checkboxes": ["a", "b"], "dropdown": "a", "multiselect": ["a", "b"], "radio": "a", "date": "2020-01-01", "datetime": "2020-01-01 00:00:00", "hidden": "hidden", } form = self.form.get_form(form_data) self.assertTrue(form.is_valid()) cleaned_data = form.cleaned_data self.assertIn("hidden", cleaned_data) self.assertNotIn("secret_honey", cleaned_data) self.assertIn("hidden", form.fields) self.assertIn("secret_honey", form.fields)