diff --git a/wagtail/contrib/forms/tests/test_models.py b/wagtail/contrib/forms/tests/test_models.py index ccf362ed6..9e17c74d0 100644 --- a/wagtail/contrib/forms/tests/test_models.py +++ b/wagtail/contrib/forms/tests/test_models.py @@ -4,11 +4,12 @@ import json from django.core import mail from django.test import TestCase +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) +from wagtail.core.models import Page from wagtail.tests.testapp.models import CustomFormPageSubmission, FormField, JadeFormPage from wagtail.tests.utils import WagtailTestUtils -from wagtail.core.models import Page -from wagtail.contrib.forms.models import FormSubmission -from wagtail.contrib.forms.tests.utils import make_form_page, make_form_page_with_custom_submission class TestFormSubmission(TestCase): @@ -54,6 +55,9 @@ class TestFormSubmission(TestCase): # check that variables defined in get_context are passed through to the template (#1429) self.assertContains(response, "
hello world
") + # check the default form_submission is added to the context + self.assertContains(response, "hello world
") + # check that the custom form_submission is added to the context + self.assertContains(response, "Username: test@email.com
") + # Check that an email was sent self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, "The subject") @@ -365,6 +372,34 @@ class TestFormSubmissionWithMultipleRecipientsAndWithCustomSubmission(TestCase, ) +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__contains='hello world').exists()) + + class TestIssue798(TestCase): fixtures = ['test.json'] diff --git a/wagtail/contrib/forms/tests/utils.py b/wagtail/contrib/forms/tests/utils.py index 7dd5918ae..a99cf6446 100644 --- a/wagtail/contrib/forms/tests/utils.py +++ b/wagtail/contrib/forms/tests/utils.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- -from wagtail.tests.testapp.models import ( - FormField, FormFieldWithCustomSubmission, FormPage, FormPageWithCustomSubmission) from wagtail.core.models import Page +from wagtail.tests.testapp.models import ( + FormField, FormFieldWithCustomSubmission, FormPage, FormPageWithCustomSubmission, + FormPageWithRedirect, RedirectFormField) def make_form_page(**kwargs): @@ -76,3 +77,42 @@ def make_form_page_with_custom_submission(**kwargs): ) 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 diff --git a/wagtail/tests/testapp/migrations/0023_formpagewithredirect_redirectformfield.py b/wagtail/tests/testapp/migrations/0023_formpagewithredirect_redirectformfield.py new file mode 100644 index 000000000..e6c7c66d6 --- /dev/null +++ b/wagtail/tests/testapp/migrations/0023_formpagewithredirect_redirectformfield.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.7 on 2017-11-17 15:52 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import modelcluster.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('wagtailcore', '0040_page_draft_title'), + ('tests', '0022_pagewithexcludedcopyfield'), + ] + + operations = [ + migrations.CreateModel( + name='FormPageWithRedirect', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')), + ('to_address', models.CharField(blank=True, help_text='Optional - form submissions will be emailed to these addresses. Separate multiple addresses by comma.', max_length=255, verbose_name='to address')), + ('from_address', models.CharField(blank=True, max_length=255, verbose_name='from address')), + ('subject', models.CharField(blank=True, max_length=255, verbose_name='subject')), + ('thank_you_redirect_page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.Page')), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + migrations.CreateModel( + name='RedirectFormField', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sort_order', models.IntegerField(blank=True, editable=False, null=True)), + ('label', models.CharField(help_text='The label of the form field', max_length=255, verbose_name='label')), + ('field_type', models.CharField(choices=[('singleline', 'Single line text'), ('multiline', 'Multi-line text'), ('email', 'Email'), ('number', 'Number'), ('url', 'URL'), ('checkbox', 'Checkbox'), ('checkboxes', 'Checkboxes'), ('dropdown', 'Drop down'), ('multiselect', 'Multiple select'), ('radio', 'Radio buttons'), ('date', 'Date'), ('datetime', 'Date/time'), ('hidden', 'Hidden field')], max_length=16, verbose_name='field type')), + ('required', models.BooleanField(default=True, verbose_name='required')), + ('choices', models.TextField(blank=True, help_text='Comma separated list of choices. Only applicable in checkboxes, radio and dropdown.', verbose_name='choices')), + ('default_value', models.CharField(blank=True, help_text='Default value. Comma separated values supported for checkboxes.', max_length=255, verbose_name='default value')), + ('help_text', models.CharField(blank=True, max_length=255, verbose_name='help text')), + ('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='form_fields', to='tests.FormPageWithRedirect')), + ], + options={ + 'abstract': False, + 'ordering': ['sort_order'], + }, + ), + ] diff --git a/wagtail/tests/testapp/models.py b/wagtail/tests/testapp/models.py index 1562ce2e8..028b86ba1 100644 --- a/wagtail/tests/testapp/models.py +++ b/wagtail/tests/testapp/models.py @@ -9,7 +9,7 @@ from django.core.exceptions import ValidationError from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.core.serializers.json import DjangoJSONEncoder from django.db import models -from django.shortcuts import render +from django.shortcuts import redirect, render from modelcluster.contrib.taggit import ClusterTaggableManager from modelcluster.fields import ParentalKey, ParentalManyToManyField from modelcluster.models import ClusterableModel @@ -435,6 +435,48 @@ JadeFormPage.content_panels = [ ] +# Form page that redirects to a different page + +class RedirectFormField(AbstractFormField): + page = ParentalKey('FormPageWithRedirect', related_name='form_fields', on_delete=models.CASCADE) + + +class FormPageWithRedirect(AbstractEmailForm): + thank_you_redirect_page = models.ForeignKey( + 'wagtailcore.Page', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+', + ) + + def get_context(self, request): + context = super(FormPageWithRedirect, self).get_context(request) + context['greeting'] = "hello world" + return context + + def render_landing_page(self, request, form_submission=None, *args, **kwargs): + """ + Renders the landing page OR if a receipt_page_redirect is chosen redirects to this page. + """ + if self.thank_you_redirect_page: + return redirect(self.thank_you_redirect_page.url, permanent=False) + + return super(FormPageWithRedirect, self).render_landing_page(request, form_submission, *args, **kwargs) + + +FormPageWithRedirect.content_panels = [ + FieldPanel('title', classname="full title"), + PageChooserPanel('thank_you_redirect_page'), + InlinePanel('form_fields', label="Form fields"), + MultiFieldPanel([ + FieldPanel('to_address', classname="full"), + FieldPanel('from_address', classname="full"), + FieldPanel('subject', classname="full"), + ], "Email") +] + + # FormPage with a custom FormSubmission class FormPageWithCustomSubmission(AbstractEmailForm): @@ -469,7 +511,7 @@ class FormPageWithCustomSubmission(AbstractEmailForm): return CustomFormPageSubmission def process_form_submission(self, form): - self.get_submission_class().objects.create( + form_submission = self.get_submission_class().objects.create( form_data=json.dumps(form.cleaned_data, cls=DjangoJSONEncoder), page=self, user=form.user ) @@ -479,6 +521,9 @@ class FormPageWithCustomSubmission(AbstractEmailForm): content = '\n'.join([x[1].label + ': ' + str(form.data.get(x[0])) for x in form.fields.items()]) send_mail(self.subject, content, addresses, self.from_address,) + # process_form_submission should now return the created form_submission + return form_submission + def serve(self, request, *args, **kwargs): if self.get_submission_class().objects.filter(page=self, user__pk=request.user.pk).exists(): return render( diff --git a/wagtail/tests/testapp/templates/tests/form_page_landing.html b/wagtail/tests/testapp/templates/tests/form_page_landing.html index 9685bd272..420f2f8c1 100644 --- a/wagtail/tests/testapp/templates/tests/form_page_landing.html +++ b/wagtail/tests/testapp/templates/tests/form_page_landing.html @@ -3,4 +3,10 @@ {% block content %}{{ greeting }}
Thank you for your feedback.
+ +{{ greeting }}
{{ self.thank_you_text|richtext }} + +Username: {{ form_submission.get_data.username }}
+ {% endblock %} diff --git a/wagtail/tests/testapp/templates/tests/form_page_with_redirect.html b/wagtail/tests/testapp/templates/tests/form_page_with_redirect.html new file mode 100644 index 000000000..386c72ada --- /dev/null +++ b/wagtail/tests/testapp/templates/tests/form_page_with_redirect.html @@ -0,0 +1,11 @@ +{% extends "tests/base.html" %} +{% load wagtailcore_tags %} + +{% block content %} +{{ greeting }}
+ +{% endblock %} diff --git a/wagtail/tests/testapp/templates/tests/form_page_with_redirect_landing.html b/wagtail/tests/testapp/templates/tests/form_page_with_redirect_landing.html new file mode 100644 index 000000000..2ec79bd55 --- /dev/null +++ b/wagtail/tests/testapp/templates/tests/form_page_with_redirect_landing.html @@ -0,0 +1,5 @@ +{% extends "tests/base.html" %} + +{% block content %} + {# Unused #} +{% endblock %}