Initial commit

This commit is contained in:
2024-08-27 20:33:44 +02:00
commit 1f1832267d
14794 changed files with 1599592 additions and 0 deletions

View File

@@ -0,0 +1,384 @@
from django import forms
from django.test import TestCase
from wagtail.contrib.forms.forms import FormBuilder
from wagtail.contrib.forms.utils import get_field_clean_name
from wagtail.models import Page
from wagtail.test.testapp.models import (
ExtendedFormField,
FormField,
FormPage,
FormPageWithCustomFormBuilder,
)
class TestFormBuilder(TestCase):
def setUp(self):
# Create a form page
home_page = Page.objects.get(url_path="/home/")
self.form_page = home_page.add_child(
instance=FormPage(
title="Contact us",
slug="contact-us",
to_address="to@email.com",
from_address="from@email.com",
subject="The subject",
)
)
FormField.objects.create(
page=self.form_page,
sort_order=1,
label="Your name",
field_type="singleline",
required=True,
)
FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your message",
field_type="multiline",
required=True,
)
FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your birthday",
field_type="date",
required=True,
)
FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your birthtime :)",
field_type="datetime",
required=True,
)
FormField.objects.create(
page=self.form_page,
sort_order=1,
label="Your email",
field_type="email",
required=True,
)
FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your homepage",
field_type="url",
required=True,
)
FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your favourite number",
field_type="number",
required=True,
)
FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your favourite text editors",
field_type="multiselect",
required=True,
choices="vim,nano,emacs",
)
FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your favourite Python IDEs",
field_type="dropdown",
required=True,
choices="PyCharm,vim,nano",
)
FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Ὕour favourite Ρython ÏÐÈ", # unicode example
help_text="Choose one",
field_type="radio",
required=True,
choices="PyCharm,vim,nano",
)
FormField.objects.create(
page=self.form_page,
sort_order=3,
label="Your choices",
field_type="checkboxes",
required=False,
choices="foo,bar,baz",
)
FormField.objects.create(
page=self.form_page,
sort_order=3,
label="I agree to the Terms of Use",
field_type="checkbox",
required=True,
)
FormField.objects.create(
page=self.form_page,
sort_order=1,
label="A Hidden Field",
field_type="hidden",
required=False,
)
# Create a form builder
self.fb = FormBuilder(self.form_page.get_form_fields())
def test_fields(self):
"""
This tests that all fields were added to the form with the correct types
"""
form_class = self.fb.get_form_class()
# All fields are present in form
field_names = form_class.base_fields.keys()
self.assertIn("your_name", field_names)
self.assertIn("your_message", field_names)
self.assertIn("your_birthday", field_names)
self.assertIn("your_birthtime", field_names)
self.assertIn("your_email", field_names)
self.assertIn("your_homepage", field_names)
self.assertIn("your_favourite_number", field_names)
self.assertIn("your_favourite_text_editors", field_names)
self.assertIn("your_favourite_python_ides", field_names)
self.assertIn("u03a5our_favourite_u03a1ython_ixd0e", field_names)
self.assertIn("your_choices", field_names)
self.assertIn("i_agree_to_the_terms_of_use", field_names)
self.assertIn("a_hidden_field", field_names)
# All fields have proper type
self.assertIsInstance(form_class.base_fields["your_name"], forms.CharField)
self.assertIsInstance(form_class.base_fields["your_message"], forms.CharField)
self.assertIsInstance(form_class.base_fields["your_birthday"], forms.DateField)
self.assertIsInstance(
form_class.base_fields["your_birthtime"], forms.DateTimeField
)
self.assertIsInstance(form_class.base_fields["your_email"], forms.EmailField)
self.assertIsInstance(form_class.base_fields["your_homepage"], forms.URLField)
self.assertIsInstance(
form_class.base_fields["your_favourite_number"], forms.DecimalField
)
self.assertIsInstance(
form_class.base_fields["your_favourite_text_editors"],
forms.MultipleChoiceField,
)
self.assertIsInstance(
form_class.base_fields["your_favourite_python_ides"], forms.ChoiceField
)
self.assertIsInstance(
form_class.base_fields["u03a5our_favourite_u03a1ython_ixd0e"],
forms.ChoiceField,
)
self.assertIsInstance(
form_class.base_fields["your_choices"], forms.MultipleChoiceField
)
self.assertIsInstance(
form_class.base_fields["i_agree_to_the_terms_of_use"], forms.BooleanField
)
self.assertIsInstance(form_class.base_fields["a_hidden_field"], forms.CharField)
# Some fields have non-default widgets
self.assertIsInstance(
form_class.base_fields["your_message"].widget, forms.Textarea
)
self.assertIsInstance(
form_class.base_fields["u03a5our_favourite_u03a1ython_ixd0e"].widget,
forms.RadioSelect,
)
self.assertIsInstance(
form_class.base_fields["your_choices"].widget, forms.CheckboxSelectMultiple
)
self.assertIsInstance(
form_class.base_fields["a_hidden_field"].widget, forms.HiddenInput
)
def test_unsaved_fields_in_form_builder_formfields(self):
"""Ensure unsaved FormField instances are added to FormBuilder.formfields dict
with a clean_name as the key.
"""
unsaved_field_1 = FormField(
page=self.form_page,
sort_order=14,
label="Unsaved field 1",
field_type="singleline",
required=True,
)
self.form_page.form_fields.add(unsaved_field_1)
unsaved_field_2 = FormField(
page=self.form_page,
sort_order=15,
label="Unsaved field 2",
field_type="singleline",
required=True,
)
self.form_page.form_fields.add(unsaved_field_2)
fb = FormBuilder(self.form_page.get_form_fields())
self.assertIn(get_field_clean_name(unsaved_field_1.label), fb.formfields)
self.assertIn(get_field_clean_name(unsaved_field_2.label), fb.formfields)
def test_newline_value_separation_in_choices_and_default_value_fields(self):
"""Ensure that the new line present between input choices or values gets formatted into choices or value list
respectively as an alternative to commas.
"""
multiselect_field = FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your favorite colours",
field_type="multiselect",
required=True,
choices="red\r\nblue\r\ngreen",
)
self.form_page.form_fields.add(multiselect_field)
dropdown_field = FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Pick your next destination",
field_type="dropdown",
required=True,
choices="hawaii\r\nparis\r\nabuja",
)
self.form_page.form_fields.add(dropdown_field)
checkboxes_field = FormField.objects.create(
page=self.form_page,
sort_order=3,
label="Do you possess these attributes",
field_type="checkboxes",
required=False,
choices="good, kind and gentle.\r\nstrong, bold and brave.",
)
self.form_page.form_fields.add(checkboxes_field)
radio_field = FormField.objects.create(
page=self.form_page,
sort_order=2,
label="Your favorite animal",
help_text="Choose one",
field_type="radio",
required=True,
choices="cat\r\ndog\r\nbird",
)
self.form_page.form_fields.add(radio_field)
checkboxes_field_with_default_value = FormField.objects.create(
page=self.form_page,
sort_order=3,
label="Choose the correct answer",
field_type="checkboxes",
required=False,
choices="a\r\nb\r\nc",
default_value="a\r\nc",
)
self.form_page.form_fields.add(checkboxes_field_with_default_value)
fb = FormBuilder(self.form_page.get_form_fields())
form_class = fb.get_form_class()
self.assertEqual(
[("red", "red"), ("blue", "blue"), ("green", "green")],
form_class.base_fields["your_favorite_colours"].choices,
)
self.assertEqual(
[("cat", "cat"), ("dog", "dog"), ("bird", "bird")],
form_class.base_fields["your_favorite_animal"].choices,
)
self.assertEqual(
[
("good, kind and gentle.", "good, kind and gentle."),
("strong, bold and brave.", "strong, bold and brave."),
],
form_class.base_fields["do_you_possess_these_attributes"].choices,
)
self.assertEqual(
[("hawaii", "hawaii"), ("paris", "paris"), ("abuja", "abuja")],
form_class.base_fields["pick_your_next_destination"].choices,
)
self.assertEqual(
["a", "c"],
form_class.base_fields["choose_the_correct_answer"].initial,
)
class TestCustomFormBuilder(TestCase):
def setUp(self):
# Create a form page
home_page = Page.objects.get(url_path="/home/")
self.form_page = home_page.add_child(
instance=FormPageWithCustomFormBuilder(
title="IT Support Request",
slug="it-support-request",
to_address="it@jenkins.com",
from_address="support@jenkins.com",
subject="Support Request Submitted",
)
)
ExtendedFormField.objects.create(
page=self.form_page,
sort_order=1,
label="Name",
field_type="singleline",
required=True,
)
def test_using_custom_form_builder(self):
"""Tests that charfield max_length is 120 characters."""
form_class = self.form_page.get_form_class()
form = form_class()
# check name field exists
self.assertIsInstance(form.base_fields["name"], forms.CharField)
# check max_length is set
self.assertEqual(form.base_fields["name"].max_length, 120)
def test_adding_custom_field(self):
"""Tests that we can add the ipaddress field, which is an extended choice."""
ExtendedFormField.objects.create(
page=self.form_page,
sort_order=1,
label="Device IP Address",
field_type="ipaddress",
required=True,
)
form_class = self.form_page.get_form_class()
form = form_class()
# check ip address field used
self.assertIsInstance(
form.base_fields["device_ip_address"], forms.GenericIPAddressField
)
def test_unsaved_fields_in_form_builder_formfields_with_clean_name_override(self):
"""
Ensure unsaved FormField instances are added to FormBuilder.formfields dict
with a clean_name that uses the `get_field_clean_name` method that can be overridden.
"""
unsaved_field_1 = ExtendedFormField(
page=self.form_page,
sort_order=14,
label="Unsaved field 1",
field_type="number",
required=True,
)
self.form_page.form_fields.add(unsaved_field_1)
unsaved_field_2 = ExtendedFormField(
page=self.form_page,
sort_order=15,
label="duplicate (suffix removed)",
field_type="singleline",
required=True,
)
self.form_page.form_fields.add(unsaved_field_2)
form_class = self.form_page.get_form_class()
form = form_class()
# See ExtendedFormField get_field_clean_name method
self.assertIn("number_field--unsaved_field_1", form.base_fields)
self.assertIn("test duplicate", form.base_fields)

View File

@@ -0,0 +1,901 @@
from django.core import mail
from django.core.exceptions import ValidationError
from django.test import TestCase, override_settings
from wagtail.contrib.forms.models import FormSubmission
from wagtail.contrib.forms.tests.utils import (
make_form_page,
make_form_page_with_custom_submission,
make_form_page_with_redirect,
make_types_test_form_page,
)
from wagtail.models import Page
from wagtail.test.testapp.models import (
CustomFormPageSubmission,
ExtendedFormField,
FormField,
FormFieldWithCustomSubmission,
FormPageWithCustomFormBuilder,
JadeFormPage,
)
from wagtail.test.utils import WagtailTestUtils
class TestFormSubmission(TestCase):
def setUp(self):
# Create a form page
self.form_page = make_form_page()
def test_get_form(self):
response = self.client.get("/contact-us/")
# Check response
self.assertContains(
response, """<label for="id_your_email">Your email</label>"""
)
self.assertTemplateUsed(response, "tests/form_page.html")
self.assertTemplateNotUsed(response, "tests/form_page_landing.html")
# HTML in help text should be escaped
self.assertContains(response, "&lt;em&gt;please&lt;/em&gt; be polite")
# check that variables defined in get_context are passed through to the template (#1429)
self.assertContains(response, "<p>hello world</p>")
@override_settings(WAGTAILFORMS_HELP_TEXT_ALLOW_HTML=True)
def test_get_form_without_help_text_escaping(self):
response = self.client.get("/contact-us/")
# HTML in help text should not be escaped
self.assertContains(response, "<em>please</em> be polite")
def test_label_escaping(self):
FormField.objects.filter(label="Your message").update(
label="Your <em>wonderful</em> message"
)
response = self.client.get("/contact-us/")
self.assertContains(
response,
"""<label for="id_your_message">Your &lt;em&gt;wonderful&lt;/em&gt; message</label>""",
)
def test_post_invalid_form(self):
response = self.client.post(
"/contact-us/",
{"your_email": "bob", "your_message": "hello world", "your_choices": ""},
)
# Check response
self.assertContains(response, "Enter a valid email address.")
self.assertTemplateUsed(response, "tests/form_page.html")
self.assertTemplateNotUsed(response, "tests/form_page_landing.html")
def test_post_valid_form(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check response
self.assertContains(response, "Thank you for your feedback.")
self.assertTemplateNotUsed(response, "tests/form_page.html")
self.assertTemplateUsed(response, "tests/form_page_landing.html")
# check that variables defined in get_context are passed through to the template (#1429)
self.assertContains(response, "<p>hello world</p>")
# check the default form_submission is added to the context
self.assertContains(response, "<li>your_email: bob@example.com</li>")
# Check that an email was sent
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, "The subject")
self.assertIn("Your message: hello world", mail.outbox[0].body)
self.assertEqual(mail.outbox[0].to, ["to@email.com"])
self.assertEqual(mail.outbox[0].from_email, "from@email.com")
# Check that form submission was saved correctly
form_page = Page.objects.get(url_path="/home/contact-us/")
self.assertTrue(
FormSubmission.objects.filter(
page=form_page, form_data__your_message="hello world"
).exists()
)
def test_post_unicode_characters(self):
self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "こんにちは、世界",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check the email
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Your message: こんにちは、世界", mail.outbox[0].body)
# Check the form submission
submission = FormSubmission.objects.get()
self.assertEqual(submission.form_data["your_message"], "こんにちは、世界")
def test_post_multiple_values(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "on", "bar": "on", "baz": "on"},
},
)
# Check response
self.assertContains(response, "Thank you for your feedback.")
self.assertTemplateNotUsed(response, "tests/form_page.html")
self.assertTemplateUsed(response, "tests/form_page_landing.html")
# Check that the three checkbox values were saved correctly
form_page = Page.objects.get(url_path="/home/contact-us/")
submission = FormSubmission.objects.filter(
page=form_page, form_data__your_message="hello world"
)
self.assertEqual(submission[0].form_data["your_choices"], ["foo", "bar", "baz"])
# Check that the all the multiple checkbox values are serialised in the
# email correctly
self.assertEqual(len(mail.outbox), 1)
self.assertIn("bar", mail.outbox[0].body)
self.assertIn("foo", mail.outbox[0].body)
self.assertIn("baz", mail.outbox[0].body)
def test_post_blank_checkbox(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {},
},
)
# Check response
self.assertContains(response, "Thank you for your feedback.")
self.assertTemplateNotUsed(response, "tests/form_page.html")
self.assertTemplateUsed(response, "tests/form_page_landing.html")
# Check that the checkbox was serialised in the email correctly
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Your choices: ", mail.outbox[0].body)
def test_invalid_from_address(self):
with self.assertRaises(ValidationError):
make_form_page(from_address="not an email")
def test_string_representation_form_submission(self):
"""
Ensure that a form submission can be logged / printed without error.
Broke when converting field to JSON - see #8927
"""
self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {},
},
)
self.assertGreaterEqual(FormSubmission.objects.count(), 1)
submission = FormSubmission.objects.first()
self.assertIn("hello world", str(submission))
class TestFormWithCustomSubmission(WagtailTestUtils, TestCase):
def setUp(self):
# Create a form page
self.form_page = make_form_page_with_custom_submission()
self.user = self.login()
def test_get_form(self):
response = self.client.get("/contact-us/")
# Check response
self.assertContains(
response, """<label for="id_your_email">Your email</label>"""
)
self.assertTemplateUsed(response, "tests/form_page_with_custom_submission.html")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
self.assertNotContains(response, "<div>You must log in first.</div>", html=True)
self.assertContains(response, "<p>Boring intro text</p>", html=True)
# check that variables defined in get_context are passed through to the template (#1429)
self.assertContains(response, "<p>hello world</p>")
def test_get_form_with_anonymous_user(self):
self.client.logout()
response = self.client.get("/contact-us/")
# Check response
self.assertNotContains(
response, """<label for="id_your_email">Your email</label>"""
)
self.assertTemplateUsed(response, "tests/form_page_with_custom_submission.html")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
self.assertContains(response, "<div>You must log in first.</div>", html=True)
self.assertNotContains(response, "<p>Boring intro text</p>", html=True)
# check that variables defined in get_context are passed through to the template (#1429)
self.assertContains(response, "<p>hello world</p>")
def test_post_invalid_form(self):
response = self.client.post(
"/contact-us/",
{"your_email": "bob", "your_message": "hello world", "your_choices": ""},
)
# Check response
self.assertContains(response, "Enter a valid email address.")
self.assertTemplateUsed(response, "tests/form_page_with_custom_submission.html")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
def test_post_valid_form(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check response
self.assertContains(response, "Thank you for your patience!")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission.html"
)
self.assertTemplateUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
# check that variables defined in get_context are passed through to the template (#1429)
self.assertContains(response, "<p>hello world</p>")
# check that the custom form_submission is added to the context
self.assertContains(response, "<p>User email: test@email.com</p>")
# Check that an email was sent
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, "The subject")
self.assertIn("Your message: hello world", mail.outbox[0].body)
self.assertEqual(mail.outbox[0].to, ["to@email.com"])
self.assertEqual(mail.outbox[0].from_email, "from@email.com")
# Check that form submission was saved correctly
form_page = Page.objects.get(url_path="/home/contact-us/")
self.assertTrue(
CustomFormPageSubmission.objects.filter(
page=form_page, form_data__your_message="hello world"
).exists()
)
def test_post_form_twice(self):
# First submission
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check response
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission.html"
)
self.assertTemplateUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
self.assertContains(response, "<p>Thank you for your patience!</p>", html=True)
self.assertNotContains(
response, "<div>The form is already filled.</div>", html=True
)
# Check that first form submission was saved correctly
submissions_qs = CustomFormPageSubmission.objects.filter(
user=self.user, page=self.form_page
)
self.assertEqual(submissions_qs.count(), 1)
self.assertTrue(
submissions_qs.filter(form_data__your_message="hello world").exists()
)
# Second submission
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check response
self.assertTemplateUsed(response, "tests/form_page_with_custom_submission.html")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
self.assertNotContains(
response, "<p>Thank you for your patience!</p>", html=True
)
self.assertContains(
response, "<div>The form is already filled.</div>", html=True
)
self.assertNotContains(response, "<div>You must log in first.</div>", html=True)
self.assertNotContains(response, "<p>Boring intro text</p>", html=True)
# Check that first submission exists and second submission wasn't saved
submissions_qs = CustomFormPageSubmission.objects.filter(
user=self.user, page=self.form_page
)
self.assertEqual(submissions_qs.count(), 1)
self.assertEqual(submissions_qs.get().form_data["your_message"], "hello world")
def test_post_unicode_characters(self):
self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "こんにちは、世界",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check the email
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Your message: こんにちは、世界", mail.outbox[0].body)
# Check the form submission
submission = CustomFormPageSubmission.objects.get()
self.assertEqual(submission.form_data["your_message"], "こんにちは、世界")
def test_post_multiple_values(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "on", "bar": "on", "baz": "on"},
},
)
# Check response
self.assertContains(response, "Thank you for your patience!")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission.html"
)
self.assertTemplateUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
# Check that the three checkbox values were saved correctly
form_page = Page.objects.get(url_path="/home/contact-us/")
submission = CustomFormPageSubmission.objects.filter(
page=form_page, form_data__your_message="hello world"
)
self.assertEqual(submission[0].form_data["your_choices"], ["foo", "bar", "baz"])
def test_post_blank_checkbox(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {},
},
)
# Check response
self.assertContains(response, "Thank you for your patience!")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission.html"
)
self.assertTemplateUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
# Check that the checkbox was serialised in the email correctly
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Your choices: None", mail.outbox[0].body)
class TestFormSubmissionWithMultipleRecipients(TestCase):
def setUp(self):
# Create a form page
self.form_page = make_form_page(to_address="to@email.com, another@email.com")
def test_invalid_to_address(self):
with self.assertRaises(ValidationError):
make_form_page(to_address="not an email")
with self.assertRaises(ValidationError):
make_form_page(to_address="to@email.com, not an email")
def test_post_valid_form(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check response
self.assertContains(response, "Thank you for your feedback.")
self.assertTemplateNotUsed(response, "tests/form_page.html")
self.assertTemplateUsed(response, "tests/form_page_landing.html")
# check that variables defined in get_context are passed through to the template (#1429)
self.assertContains(response, "<p>hello world</p>")
# Check that one email was sent, but to two recipients
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, "The subject")
self.assertIn("Your message: hello world", mail.outbox[0].body)
self.assertEqual(mail.outbox[0].from_email, "from@email.com")
self.assertEqual(set(mail.outbox[0].to), {"to@email.com", "another@email.com"})
# Check that form submission was saved correctly
form_page = Page.objects.get(url_path="/home/contact-us/")
self.assertTrue(
FormSubmission.objects.filter(
page=form_page, form_data__your_message="hello world"
).exists()
)
class TestFormSubmissionWithMultipleRecipientsAndWithCustomSubmission(
WagtailTestUtils, TestCase
):
def setUp(self):
# Create a form page
self.form_page = make_form_page_with_custom_submission(
to_address="to@email.com, another@email.com"
)
self.user = self.login()
def test_post_valid_form(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check response
self.assertContains(response, "Thank you for your patience!")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_submission.html"
)
self.assertTemplateUsed(
response, "tests/form_page_with_custom_submission_landing.html"
)
# check that variables defined in get_context are passed through to the template (#1429)
self.assertContains(response, "<p>hello world</p>")
# Check that one email was sent, but to two recipients
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, "The subject")
self.assertIn("Your message: hello world", mail.outbox[0].body)
self.assertEqual(mail.outbox[0].from_email, "from@email.com")
self.assertEqual(set(mail.outbox[0].to), {"to@email.com", "another@email.com"})
# Check that form submission was saved correctly
form_page = Page.objects.get(url_path="/home/contact-us/")
self.assertTrue(
CustomFormPageSubmission.objects.filter(
page=form_page, form_data__your_message="hello world"
).exists()
)
class TestFormWithRedirect(TestCase):
def setUp(self):
# Create a form page
self.form_page = make_form_page_with_redirect(
to_address="to@email.com, another@email.com"
)
def test_post_valid_form(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "", "bar": "", "baz": ""},
},
)
# Check response
self.assertRedirects(response, "/")
# Check that one email was sent, but to two recipients
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, "The subject")
self.assertIn("Your message: hello world", mail.outbox[0].body)
self.assertEqual(mail.outbox[0].from_email, "from@email.com")
self.assertEqual(set(mail.outbox[0].to), {"to@email.com", "another@email.com"})
# Check that form submission was saved correctly
form_page = Page.objects.get(url_path="/home/contact-us/")
self.assertTrue(
FormSubmission.objects.filter(
page=form_page, form_data__your_message="hello world"
).exists()
)
class TestFormPageWithCustomFormBuilder(WagtailTestUtils, TestCase):
def setUp(self):
home_page = Page.objects.get(url_path="/home/")
form_page = home_page.add_child(
instance=FormPageWithCustomFormBuilder(
title="Support Request",
slug="support-request",
to_address="it@jenkins.com",
from_address="support@jenkins.com",
subject="Support Request Submitted",
)
)
ExtendedFormField.objects.create(
page=form_page,
sort_order=1,
label="Name",
field_type="singleline", # singleline field will be max_length 120
required=True,
)
ExtendedFormField.objects.create(
page=form_page,
sort_order=1,
label="Device IP Address",
field_type="ipaddress",
required=True,
)
def test_get_form(self):
response = self.client.get("/support-request/")
# Check response
self.assertTemplateUsed(
response, "tests/form_page_with_custom_form_builder.html"
)
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_form_builder_landing.html"
)
self.assertContains(response, "<title>Support Request</title>", html=True)
# check that max_length attribute has been passed into form
self.assertContains(
response,
'<input type="text" name="name" required maxlength="120" id="id_name" />',
html=True,
)
# check ip address field has rendered
self.assertContains(
response,
'<input type="text" name="device_ip_address" required id="id_device_ip_address" />',
html=True,
)
def test_post_invalid_form(self):
response = self.client.post(
"/support-request/",
{
"name": "very long name longer than 120 characters" * 3, # invalid
"device_ip_address": "192.0.2.30", # valid
},
)
# Check response with invalid character count
self.assertContains(
response, "Ensure this value has at most 120 characters (it has 123)"
)
self.assertTemplateUsed(
response, "tests/form_page_with_custom_form_builder.html"
)
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_form_builder_landing.html"
)
response = self.client.post(
"/support-request/",
{
"name": "Ron Johnson", # valid
"device_ip_address": "3300.192.0.2.30", # invalid
},
)
# Check response with invalid character count
self.assertContains(response, "Enter a valid IPv4 or IPv6 address.")
self.assertTemplateUsed(
response, "tests/form_page_with_custom_form_builder.html"
)
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_form_builder_landing.html"
)
def test_post_valid_form(self):
response = self.client.post(
"/support-request/",
{
"name": "Ron Johnson",
"device_ip_address": "192.0.2.30",
},
)
# Check response
self.assertContains(response, "Thank you for submitting a Support Request.")
self.assertContains(response, "Ron Johnson")
self.assertContains(response, "192.0.2.30")
self.assertTemplateNotUsed(
response, "tests/form_page_with_custom_form_builder.html"
)
self.assertTemplateUsed(
response, "tests/form_page_with_custom_form_builder_landing.html"
)
class TestCleanedDataEmails(TestCase):
def setUp(self):
# Create a form page
self.form_page = make_types_test_form_page()
def test_empty_field_presence(self):
self.client.post("/contact-us/", {})
# Check the email
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Single line text: ", mail.outbox[0].body)
self.assertIn("Multiline: ", mail.outbox[0].body)
self.assertIn("Email: ", mail.outbox[0].body)
self.assertIn("Number: ", mail.outbox[0].body)
self.assertIn("URL: ", mail.outbox[0].body)
self.assertIn("Checkbox: ", mail.outbox[0].body)
self.assertIn("Checkboxes: ", mail.outbox[0].body)
self.assertIn("Drop down: ", mail.outbox[0].body)
self.assertIn("Multiple select: ", mail.outbox[0].body)
self.assertIn("Radio buttons: ", mail.outbox[0].body)
self.assertIn("Date: ", mail.outbox[0].body)
self.assertIn("Datetime: ", mail.outbox[0].body)
def test_email_field_order(self):
self.client.post("/contact-us/", {})
line_beginnings = [
"Single line text: ",
"Multiline: ",
"Email: ",
"Number: ",
"URL: ",
"Checkbox: ",
"Checkboxes: ",
"Drop down: ",
"Multiple select: ",
"Radio buttons: ",
"Date: ",
"Datetime: ",
]
# Check the email
self.assertEqual(len(mail.outbox), 1)
email_lines = mail.outbox[0].body.split("\n")
for beginning in line_beginnings:
message_line = email_lines.pop(0)
self.assertTrue(message_line.startswith(beginning))
@override_settings(SHORT_DATE_FORMAT="m/d/Y")
def test_date_normalization(self):
self.client.post(
"/contact-us/",
{
"date": "12/31/17",
},
)
# Check the email
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Date: 12/31/2017", mail.outbox[0].body)
self.client.post(
"/contact-us/",
{
"date": "12/31/1917",
},
)
# Check the email
self.assertEqual(len(mail.outbox), 2)
self.assertIn("Date: 12/31/1917", mail.outbox[1].body)
@override_settings(SHORT_DATETIME_FORMAT="m/d/Y P")
def test_datetime_normalization(self):
self.client.post(
"/contact-us/",
{
"datetime": "12/31/17 4:00:00",
},
)
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Datetime: 12/31/2017 4 a.m.", mail.outbox[0].body)
self.client.post(
"/contact-us/",
{
"datetime": "12/31/1917 21:19",
},
)
self.assertEqual(len(mail.outbox), 2)
self.assertIn("Datetime: 12/31/1917 9:19 p.m.", mail.outbox[1].body)
self.client.post(
"/contact-us/",
{
"datetime": "1910-12-21 21:19:12",
},
)
self.assertEqual(len(mail.outbox), 3)
self.assertIn("Datetime: 12/21/1910 9:19 p.m.", mail.outbox[2].body)
@override_settings(USE_I18N=True, LANGUAGE_CODE="de")
def test_date_localization(self):
self.client.post(
"/contact-us/",
{
"date": "2017-12-31",
},
)
# Check the email
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Date: 31.12.2017", mail.outbox[0].body)
@override_settings(USE_I18N=True, LANGUAGE_CODE="de")
def test_datetime_localization(self):
self.client.post(
"/contact-us/",
{
"datetime": "1910-12-21 21:19:12",
},
)
# Check the email
self.assertEqual(len(mail.outbox), 1)
self.assertIn("Datetime: 21.12.1910 21:19", mail.outbox[0].body)
class TestIssue798(WagtailTestUtils, TestCase):
fixtures = ["test.json"]
def setUp(self):
self.login(username="siteeditor", password="password")
self.form_page = Page.objects.get(url_path="/home/contact-us/").specific
# Add a number field to the page
FormField.objects.create(
page=self.form_page,
label="Your favourite number",
field_type="number",
)
def test_post(self):
response = self.client.post(
"/contact-us/",
{
"your_email": "bob@example.com",
"your_message": "hello world",
"your_choices": {"foo": "", "bar": "", "baz": ""},
"your_favourite_number": "7.3",
},
)
# Check response
self.assertTemplateUsed(response, "tests/form_page_landing.html")
# Check that form submission was saved correctly
self.assertTrue(
FormSubmission.objects.filter(
page=self.form_page, form_data__your_message="hello world"
).exists()
)
self.assertTrue(
FormSubmission.objects.filter(
page=self.form_page, form_data__your_favourite_number="7.3"
).exists()
)
class TestNonHtmlExtension(TestCase):
fixtures = ["test.json"]
def test_non_html_extension(self):
form_page = JadeFormPage(title="test")
self.assertEqual(
form_page.landing_page_template, "tests/form_page_landing.jade"
)
class TestFormFieldCleanNameCreation(WagtailTestUtils, TestCase):
fixtures = ["test.json"]
def setUp(self):
self.login(username="siteeditor", password="password")
self.form_page = Page.objects.get(
url_path="/home/contact-us-one-more-time/"
).specific
def test_form_field_clean_name_creation(self):
"""creating a new field should use clean_name format (anyascii snake_case)"""
field = FormFieldWithCustomSubmission.objects.create(
page=self.form_page,
label="Telefón-nummer",
field_type="number",
)
self.assertEqual(field.clean_name, "telefon_nummer")
class TestFormFieldCleanNameCreationOverride(WagtailTestUtils, TestCase):
def setUp(self):
# Create a form page
home_page = Page.objects.get(url_path="/home/")
self.form_page = home_page.add_child(
instance=FormPageWithCustomFormBuilder(
title="Richiesta Gelato",
slug="ice-cream-request",
to_address="scoops@pro-eis.co.it",
from_address="scoops@pro-eis.co.it",
subject="Gelato in arrivo",
)
)
def test_form_field_clean_name_override(self):
"""
Creating a new field should use the overridden method
See ExtendedFormField get_field_clean_name method
"""
field = ExtendedFormField.objects.create(
page=self.form_page,
sort_order=1,
label="quanti ge·là·to?",
field_type="number", # only number fields will add the ID as a prefix to the clean_name
required=True,
)
self.assertEqual(field.clean_name, "number_field--quanti_gelato")

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,224 @@
from wagtail.models import Page
from wagtail.test.testapp.models import (
FormField,
FormFieldWithCustomSubmission,
FormPage,
FormPageWithCustomSubmission,
FormPageWithRedirect,
RedirectFormField,
)
def make_form_page(**kwargs):
kwargs.setdefault("title", "Contact us")
kwargs.setdefault("slug", "contact-us")
kwargs.setdefault("to_address", "to@email.com")
kwargs.setdefault("from_address", "from@email.com")
kwargs.setdefault("subject", "The subject")
home_page = Page.objects.get(url_path="/home/")
form_page = home_page.add_child(instance=FormPage(**kwargs))
FormField.objects.create(
page=form_page,
sort_order=1,
label="Your email",
field_type="email",
required=True,
)
FormField.objects.create(
page=form_page,
sort_order=2,
label="Your message",
field_type="multiline",
required=True,
help_text="<em>please</em> be polite",
)
FormField.objects.create(
page=form_page,
sort_order=3,
label="Your choices",
field_type="checkboxes",
required=False,
choices="foo,bar,baz",
)
return form_page
def make_form_page_with_custom_submission(**kwargs):
kwargs.setdefault("title", "Contact us")
kwargs.setdefault("intro", "<p>Boring intro text</p>")
kwargs.setdefault("thank_you_text", "<p>Thank you for your patience!</p>")
kwargs.setdefault("slug", "contact-us")
kwargs.setdefault("to_address", "to@email.com")
kwargs.setdefault("from_address", "from@email.com")
kwargs.setdefault("subject", "The subject")
home_page = Page.objects.get(url_path="/home/")
form_page = home_page.add_child(instance=FormPageWithCustomSubmission(**kwargs))
FormFieldWithCustomSubmission.objects.create(
page=form_page,
sort_order=1,
label="Your email",
field_type="email",
required=True,
)
FormFieldWithCustomSubmission.objects.create(
page=form_page,
sort_order=2,
label="Your message",
field_type="multiline",
required=True,
)
FormFieldWithCustomSubmission.objects.create(
page=form_page,
sort_order=3,
label="Your choices",
field_type="checkboxes",
required=False,
choices="foo,bar,baz",
)
return form_page
def make_form_page_with_redirect(**kwargs):
kwargs.setdefault("title", "Contact us")
kwargs.setdefault("slug", "contact-us")
kwargs.setdefault("to_address", "to@email.com")
kwargs.setdefault("from_address", "from@email.com")
kwargs.setdefault("subject", "The subject")
home_page = Page.objects.get(url_path="/home/")
kwargs.setdefault("thank_you_redirect_page", home_page)
form_page = home_page.add_child(instance=FormPageWithRedirect(**kwargs))
# form_page.thank_you_redirect_page = home_page
RedirectFormField.objects.create(
page=form_page,
sort_order=1,
label="Your email",
field_type="email",
required=True,
)
RedirectFormField.objects.create(
page=form_page,
sort_order=2,
label="Your message",
field_type="multiline",
required=True,
)
RedirectFormField.objects.create(
page=form_page,
sort_order=3,
label="Your choices",
field_type="checkboxes",
required=False,
choices="foo,bar,baz",
)
return form_page
def make_types_test_form_page(**kwargs):
kwargs.setdefault("title", "Contact us")
kwargs.setdefault("slug", "contact-us")
kwargs.setdefault("to_address", "to@email.com")
kwargs.setdefault("from_address", "from@email.com")
kwargs.setdefault("subject", "The subject")
home_page = Page.objects.get(url_path="/home/")
form_page = home_page.add_child(instance=FormPage(**kwargs))
FormField.objects.create(
page=form_page,
sort_order=1,
label="Single line text",
field_type="singleline",
required=False,
)
FormField.objects.create(
page=form_page,
sort_order=2,
label="Multiline",
field_type="multiline",
required=False,
)
FormField.objects.create(
page=form_page,
sort_order=3,
label="Email",
field_type="email",
required=False,
)
FormField.objects.create(
page=form_page,
sort_order=4,
label="Number",
field_type="number",
required=False,
)
FormField.objects.create(
page=form_page,
sort_order=5,
label="URL",
field_type="url",
required=False,
)
FormField.objects.create(
page=form_page,
sort_order=6,
label="Checkbox",
field_type="checkbox",
required=False,
)
FormField.objects.create(
page=form_page,
sort_order=7,
label="Checkboxes",
field_type="checkboxes",
required=False,
choices="foo,bar,baz",
)
FormField.objects.create(
page=form_page,
sort_order=8,
label="Drop down",
field_type="dropdown",
required=False,
choices="spam,ham,eggs",
)
FormField.objects.create(
page=form_page,
sort_order=9,
label="Multiple select",
field_type="multiselect",
required=False,
choices="qux,quux,quuz,corge",
)
FormField.objects.create(
page=form_page,
sort_order=10,
label="Radio buttons",
field_type="radio",
required=False,
choices="wibble,wobble,wubble",
)
FormField.objects.create(
page=form_page,
sort_order=11,
label="Date",
field_type="date",
required=False,
)
FormField.objects.create(
page=form_page,
sort_order=12,
label="Datetime",
field_type="datetime",
required=False,
)
return form_page